/* NOTICE
    OpenJaWS - Open Java Weather Station
    
    Copyright (C) 2008 Grant Gardner <grant@lastweekend.com.au>
    
    OpenJaWS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
NOTICE */

package au.com.lastweekend.openjaws.plugins;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.lastweekend.openjaws.api.Readings;
import au.com.lastweekend.openjaws.api.WeatherPlugin;
import au.com.lastweekend.openjaws.api.WeatherPluginException;

import com.thoughtworks.xstream.XStream;

/**
 * On first read will load the last persisted readings from an XML file.
 * 
 * Every reading will be persisted so if the station stops it can restart from that point using historical data
 * 
 * @author grant@lastweekend.com.au
 * @version $Id: codetemplates.xml,v 1.2 2005/01/22 06:53:11 ggardner Exp $
 */
public class PersistentReadingsPlugin extends DecoratedWeatherPlugin {

    private static final Logger LOG = LoggerFactory.getLogger(PersistentReadingsPlugin.class);
    private File readingsFile;

    public PersistentReadingsPlugin(WeatherPlugin decorated) {

        super(decorated);

    }

    @PostConstruct
    public void init() {

        if (isEnabled()) {
            LOG.info("Enabled, writing to " + readingsFile.getAbsolutePath());
        } else {
            LOG.info("Disabled");
        }
    }

    @Override
    protected void preProcess(Readings readings) throws WeatherPluginException {

        if (readings.getReadingTime() == null) {
            loadReadings(readings);
        }
    }

    @Override
    protected void postProcess(Readings readings) throws WeatherPluginException {

        storeReadings(readings);
    }

    private void loadReadings(Readings readings) throws WeatherPluginException {

        XStream xStream = new XStream();
        if (readingsFile.exists()) {
            try {
                Readings xReadings = (Readings) xStream.fromXML(new FileInputStream(readingsFile));
                readings.copy(xReadings);
                LOG.info(String.format("Restored reading values from %tc", readings.getReadingTime()));
            } catch (FileNotFoundException e) {
                LOG.error("Unable to find " + readingsFile.getAbsolutePath(), e);
            }
        } else {
            LOG.warn("Persisted readings not available in " + readingsFile.getAbsolutePath());
        }
    }

    private void storeReadings(Readings readings) throws WeatherPluginException {

        try {
            XStream xStream = new XStream();
            xStream.toXML(readings, new FileOutputStream(readingsFile));
            LOG.debug("Stored readings to " + readingsFile.getAbsolutePath());
        } catch (FileNotFoundException e) {

            throw new WeatherPluginException("Unable to persist readings", e);
        }

    }

    @Override
    public boolean isEnabled() {

        return super.isEnabled() && readingsFile != null;
    }

    public File getReadingsFile() {

        return readingsFile;
    }

    public void setReadingsFile(File readingsFile) {

        LOG.debug("Set readings file to " + readingsFile.getName());
        this.readingsFile = readingsFile;
    }

}
